﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ASpect.Logic
{
    public class Graphic
    {
        #region Локальные переменные
        int _dx, _dy, _x0, _x1, _y0, _y1, _fsize, _dxgnum, _xgnum, _ghd, _gfmult, _fmaxx =22500;
        System.Drawing.Graphics _Canvas;
        float _maxy = 1f;
        #endregion

        #region Приватные методы
        private void _DrawAxes(System.Drawing.Color color)
        {
            System.Drawing.Pen GPen = new System.Drawing.Pen(color);
            System.Drawing.SolidBrush GBrush = new System.Drawing.SolidBrush(color);
            System.Drawing.Font GFont = new System.Drawing.Font("Times New Roman", _fsize);
            _Canvas.DrawLines(GPen, new System.Drawing.Point[] { new System.Drawing.Point(_x0, _y0), new System.Drawing.Point(_x0, _y1), new System.Drawing.Point(_x1, _y1) });//отрисовка осей
            _Canvas.DrawLines(GPen, new System.Drawing.Point[] { new System.Drawing.Point(_x1 - 2, _y1 - 2), new System.Drawing.Point(_x1, _y1), new System.Drawing.Point(_x1 - 2, _y1 + 2) });//отрисовка стрелочек на грфике
            _Canvas.DrawLines(GPen, new System.Drawing.Point[] { new System.Drawing.Point(_x0 - 2, _y0 + 2), new System.Drawing.Point(_x0, _y0), new System.Drawing.Point(_x0 + 2, _y0 + 2) });
            _Canvas.DrawString("50", GFont, GBrush, new System.Drawing.PointF(_x0, _y1 +_ghd+ 1));
            for (int i = 1; i <= _xgnum; i++)//отрисовка делений по оси x и их подписывание
            {
                _Canvas.DrawLine(GPen, new System.Drawing.Point((_x0 + i * _dxgnum), _y1 - _ghd), new System.Drawing.Point((_x0 + i * _dxgnum), _y1 + _ghd));
                _Canvas.DrawString((((_gfmult*i+50)<1000) ? ((_gfmult * i+50).ToString()) : (Math.Round((((double)(_gfmult*i+50))/((double)1000)),1).ToString()+"k")), GFont, GBrush, new System.Drawing.PointF((_x0+i*_dxgnum),_y1+_ghd+1) );
            }
        }
        private void _DrawGraphic(float[] Amp, System.Drawing.Color color, System.Drawing.Color fillcolor)
        {
            float maxamp = 0f;
            int x01, x02, y01, y02;
            System.Drawing.Pen Gpen = new System.Drawing.Pen(color);
            System.Drawing.SolidBrush Gbrush = new System.Drawing.SolidBrush(fillcolor);
            for (int i = 0; i < Amp.Length; i++)
                if (Amp[i] > maxamp) maxamp = Amp[i];
            if (maxamp > 0f)
                for (int i = 1; i < Amp.Length; i++)
                {
                    x01 = _x0 + (int)Math.Round((float)(i - 1) * ((float)_dx / (float)Amp.Length));
                    y01 = _y1 - (int)(Amp[i - 1] / _maxy * (float)_dy);
                    x02 = _x0 + (int)Math.Round((float)i * ((float)_dx / (float)Amp.Length));
                    y02 = _y1 - (int)(Amp[i] / _maxy * (float)_dy);
                    if (((x01 != x02) ^ (y01 != y02)) || ((x01 != x02) && (y01 != y02)))
                    {
                        _Canvas.FillPolygon(Gbrush, new System.Drawing.Point[] { new System.Drawing.Point (x01, y01), new System.Drawing.Point (x02, y02), new System.Drawing.Point (x02, _y1), new System.Drawing.Point (x01, _y1)});
                        _Canvas.DrawLine(Gpen, x01, y01, x02, y02);
                    }
                   
                }
        }
        #endregion

        #region Публичные методы
        public void DrawAxes()
        {
            _DrawAxes(System.Drawing.Color.Black);
        }
        public void DrawAxes(System.Drawing.Color color)
        {
            _DrawAxes(color);
        }
        public void DrawGraphic(float[] Amp)
        {
            _DrawGraphic(Amp, System.Drawing.Color.Red, System.Drawing.Color.LightGray); 
        }
        public void DrawGraphic(float[] Amp, System.Drawing.Color color, System.Drawing.Color fillcolor)
        {
            _DrawGraphic(Amp, color, fillcolor);
        }
        public void Clear()
        {
            _Canvas.Clear(System.Drawing.Color.White);
        }
        public void Zoom(int i)
        {
            _maxy = 1f / (float)i;
        }
        public void ZoomDefault()
        {
            _maxy = 1f;
        }
        public void Resize(int x0, int x1, int y0, int y1, System.Drawing.Graphics Canvas)
        {
            _x0 = x0;
            _x1 = x1;
            _y0 = y0;
            _y1 = y1;
            _dx = x1 - x0;//ширина окна с графиком
            _dy = y1 - y0;//высота окна с графиком
            /*int dygnum = 20;//расстояние между делениями на графике по оси y
            int ygnum = dy / dygnum;//количество делений по оси y
            for (i = 1; ygnum > 9; i++)
            {
                ygnum = (int) (ygnum / 10);
            }
            ygnum = ygnum * i * 10;*/
            _xgnum = (_dx-20) / _dxgnum; // количество делений по оси x
            _ghd = (_dy / 100 > 1 ? _dy / 100 : 1); //высота делений
            _gfmult = (_fmaxx - 50) / _xgnum;
            _Canvas = Canvas;
        }
        #endregion

        #region Конструкторы
        public Graphic(int x0, int x1, int y0, int y1, System.Drawing.Graphics Canvas)
        {
            _x0 = x0;
            _x1 = x1;
            _y0 = y0;
            _y1 = y1;
            _dx = x1 - x0;//ширина окна с графиком
            _dy = y1 - y0;//высота окна с графиком
            _fsize = 5;//размер шрифта
            /*int dygnum = 20;//расстояние между делениями на графике по оси y
            int ygnum = dy / dygnum;//количество делений по оси y
            for (i = 1; ygnum > 9; i++)
            {
                ygnum = (int) (ygnum / 10);
            }
            ygnum = ygnum * i * 10;*/
            _dxgnum = 20;//расстояние между делениями на графике по оси x
            _xgnum = (_dx-20) / _dxgnum; // количество делений по оси x
            _ghd = (_dy / 100 > 1 ? _dy / 100 : 1); //высота делений
            _gfmult = (_fmaxx-50) / _xgnum;
            _Canvas = Canvas;
        }
        #endregion

    }
}
